/*
  学习目标：搭建登录-封装Input组件
  需求：
    1. Input要支持传不同的name
    2. Input要支持扩展右侧内容

  步骤：
    1. 提取Input静态结构，到Input组件中
    2. 提取样式，改造为CSSModules的方式，让Input组件，自己管理自己的样式
*/
import Input from '@/components/Input';
import NavBar from '@/components/NavBar';
import { useFormik } from 'formik';
import styles from './index.module.scss';

// Yup 可适用于更复杂的表单格式校验，如校验是否为数字，是否为空，是否为某个内置格式
// Yup的优点: 1.链式调用  2.内置校验规则
import * as Yup from 'yup';
import { useDispatch } from 'react-redux';
import { getCodeAction, loginAction } from '@/store/action/user';
import { useEffect, useRef, useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import { Toast } from 'antd-mobile';
import { LocationStateType } from '@/components/AuthRoute';

export default function Login() {
  const history = useHistory();
  const location = useLocation<LocationStateType>();
  console.log('location  ----->  ', location);
  const dispatch = useDispatch();
  // 导入formik,创建form实例对象
  const formik = useFormik({
    initialValues: {
      mobile: '13500000000',
      code: '',
    },
    onSubmit: async (values) => {
      console.log('value  ----->  ', values);
      await dispatch(loginAction(values));
      // 轻提示
      Toast.show({ content: '登陆成功' });
      // 接收传来的fromPath，表示回跳到那个页面上
      const { state = {} as LocationStateType } = location;
      // state是可选参数，有可能为undefined,使用默认值处理回跳的路径
      const { fromPath = '/' } = state;
      // push会在历史记录，新增一条记录
      history.replace(fromPath);
    },
    validationSchema: Yup.object().shape({
      // 手机号校验
      mobile: Yup.string()
        .required('手机号不能为空')
        .matches(/^1[3-9]\d{9}$/, '手机号格式错误'),
      // 验证码校验
      code: Yup.string()
        .required('验证码不能为空')
        .matches(/^\d{6}$/, '验证码格式错误'),
    }),
    // 设置校验函数validate
    // validate: (values) => {
    //   // 创建errors对象
    //   const errors = {} as typeof values;
    //   // 如果校验mobile,不同返回的对象,有mobile
    //   if (!/^1[3-9]\d{9}$/.test(values.mobile)) {
    //     errors.mobile = '手机号格式错误';
    //   }
    //   // 如果校验code不通过,返回的对象,有code字段
    //   if (!/^\d{6}$/.test(values.code)) {
    //     errors.code = '验证码格式错误';
    //   }
    //   return errors; //返回的对象,相当于state,可以改变界面
    // 在 validationSchema设置校验规则

    // },
  });

  const [seconds, setSeconds] = useState(0);
  const timeId = useRef(-1);

  const handleGetCode = () => {
    dispatch(getCodeAction(formik.values.mobile));
    setSeconds(60);
    // 开启定时器 ,这种写法 1定时器内部状态无法更新 2组件卸载没有清理定时器。
    // let timeId = setInterval(() => {
    //   // 每秒钟-1
    //   // setState是异步的,要通过根据新旧值,计算新值 ,使用setSecond((preState)=>newState)
    //   setSeconds((oldValue) => {
    //     if (oldValue === 1) {
    //       clearInterval(timeId);
    //     }
    //     return oldValue - 1;
    //   });
    // }, 100);

    // ref定时器写法
    timeId.current = window.setInterval(() => {
      // 💥当我们每次都想要获取到最新的状态，需要写成 箭头函数 的形式
      setSeconds((oldValue) => {
        if (oldValue === 1) {
          clearInterval(timeId.current);
        }
        return oldValue - 1;
      });
    });
  };
  useEffect(() => {
    return () => {
      // 组件卸载清理定时器，避免内存泄漏
      clearInterval(timeId.current);
    };
  }, []);
  return (
    <div className={styles.root}>
      <NavBar>登录</NavBar>
      <div className="content">
        {/* 标题 */}
        <h3>短信登录</h3>
        {/* 绑定form的提交事件和表单元素的受控 */}
        <form onSubmit={formik.handleSubmit}>
          {/* 手机号输入框 */}
          <div className="input-item">
            <div className="input-box">
              <Input
                autoFocus
                className="input"
                placeholder="请输入手机号"
                autoComplete="off"
                type="text"
                name="mobile"
                maxLength={11}
                // 设置errormsg.
                errorMsg={formik.touched.mobile ? formik.errors.mobile : ''}
                onChange={formik.handleChange}
                value={formik.values.mobile}
                onBlur={formik.handleBlur}
              />
            </div>
          </div>

          {/* 短信验证码输入框 */}
          <div className="input-item">
            <div className="input-box">
              <input />
              <Input
                className="input"
                placeholder="请输入验证码"
                autoComplete="off"
                type="text"
                name="code"
                maxLength={6}
                errorMsg={formik.touched.code ? formik.errors.code : ''}
                extra={
                  <span onClick={handleGetCode}>
                    {seconds === 0 ? '获取验证码' : `${seconds}秒倒计时`}
                  </span>
                }
                onChange={formik.handleChange}
                value={formik.values.code}
                onBlur={formik.handleBlur}
              />
            </div>
          </div>

          {/* 登录按钮 */}
          <button
            type="submit"
            className="login-btn"
            disabled={!formik.isValid}
          >
            登录
          </button>
        </form>
      </div>
    </div>
  );
}
